package org.adempiere.webui.dashboard;

import java.io.File;
import java.io.FileNotFoundException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Properties;
import java.util.logging.Level;

import javax.activation.MimetypesFileTypeMap;

import org.adempiere.exceptions.DBException;
import org.adempiere.model.MBroadcastMessage;
import org.adempiere.webui.component.Checkbox;
import org.adempiere.webui.component.DynamicMediaLink;
import org.adempiere.webui.component.Grid;
import org.adempiere.webui.component.GridFactory;
import org.adempiere.webui.component.Group;
import org.adempiere.webui.component.Row;
import org.adempiere.webui.component.Rows;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.util.ServerPushTemplate;
import org.compiere.model.MAttachment;
import org.compiere.model.MAttachmentEntry;
import org.compiere.model.MNote;
import org.compiere.model.MRefList;
import org.compiere.model.MSysConfig;
import org.compiere.model.MUser;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
import org.idempiere.broadcast.BroadcastMsgUtil;
import org.idempiere.broadcast.IBroadcastMsgPopup;
import org.osgi.service.event.EventHandler;
import org.zkoss.util.media.AMedia;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Html;

public class DPBroadCastMessage  extends DashboardPanel implements IBroadcastMsgPopup, EventListener<Event>, EventHandler {

	private static final long serialVersionUID = -4761986600721482123L;

	private static final CLogger logger = CLogger.getCLogger(DPBroadCastMessage.class);

	private ArrayList<MBroadcastMessage> mbMessages = null;

	private Grid bmGrid;
	private Rows bmRows;
	private Hashtable<Integer, Checkbox> hashAcknowledged = new Hashtable<Integer, Checkbox>();

	boolean isOpen = true;
	
	public DPBroadCastMessage() {
		super();

		init();
		
		initGrid();
		
		initRows();
	}

	private void init() {
		isOpen = MSysConfig.getBooleanValue("IDCHINA_ZK_DPBroadCastMessage_ISOPEN", true, Env.getAD_Client_ID(Env.getCtx()));
		hashAcknowledged.clear();
	}
	
	private void initGrid() {
		bmGrid = GridFactory.newGridLayout();
		bmGrid.setMold("paging");
		bmGrid.setPageSize(MSysConfig.getIntValue("IDCHINA_ZK_PAGING_SIZE_DPBroadCastMessage", 2, Env.getAD_Client_ID(Env.getCtx())));
		bmGrid.setPagingPosition("top");
		this.appendChild(bmGrid);
	}
	
	private void initRows() {
		
		if (bmGrid.getRows()!=null)
			bmGrid.removeChild(bmRows);
		
		bmRows = bmGrid.newRows();
		
		BroadcastMsgUtil.showPendingMessage(Env.getAD_User_ID(Env.getCtx()), this);
		if (mbMessages != null)
		{
			for(int i = 0; mbMessages.size() > i; i++)
			{
				createBMView(mbMessages.get(i),bmRows);
			}
		}
		else
		{
			Row row = bmRows.newRow();
			row.appendChild(new Html(Msg.getMsg(Env.getCtx(), "NotFound")));
		}
	}

	private void createBMView(MBroadcastMessage mbMessage,Rows bmRows) {
		
		Row outerRow = new Row();
		bmRows.appendChild(outerRow);

		Grid innerGrid = new Grid();
		outerRow.appendChild(innerGrid);

		Rows innerRows = new Rows();
		innerGrid.appendChild(innerRows);
		
		String groupTitle = MRefList.getListDescription(Env.getCtx(), "SuperiorLevel", mbMessage.get_ValueAsString("SuperiorLevel")) + mbMessage.get_ValueAsString("Title");
		
		if(groupTitle==null || groupTitle.equals("")){
			groupTitle = MUser.get(Env.getCtx(), mbMessage.getCreatedBy()).getName() 
					+ " " 
					+ Env.getLanguage(Env.getCtx()).getDateTimeFormat().format(mbMessage.getUpdated());		
		}


		
		Group innerRowGroup = new Group(groupTitle);
		innerRows.appendChild(innerRowGroup);

		String bmFrequency = mbMessage.getBroadcastFrequency();
		if ( bmFrequency.equals(MBroadcastMessage.BROADCASTFREQUENCY_UntilAcknowledge)
				 || bmFrequency.equals(MBroadcastMessage.BROADCASTFREQUENCY_UntilExpirationOrAcknowledge)){
			Row checkRow = new Row();
			Checkbox acknowledged = new Checkbox();
			hashAcknowledged.put(mbMessage.get_ID(), acknowledged);
			acknowledged.setSelected(false);
			acknowledged.setLabel(Msg.getMsg(Env.getCtx(),"Acknowledge"));
			acknowledged.addEventListener("onClick", this);
			checkRow.appendChild(acknowledged);
			checkRow.setGroup(innerRowGroup);
			innerRows.appendChild(checkRow);
		};
		
		Row innerRow = new Row();
		Html html = new Html(mbMessage.get_Translation(MBroadcastMessage.COLUMNNAME_BroadcastMessage));

		innerRow.appendChild(html);
		innerRow.setGroup(innerRowGroup);
		innerRows.appendChild(innerRow);

		MAttachment attachment = mbMessage.getAttachment();
		if(attachment != null)
		{
			MAttachmentEntry[] entry =attachment.getEntries();
			for(int j = 0; entry.length > j; j++)
			{
				MimetypesFileTypeMap mimeMap = new MimetypesFileTypeMap();
				File file = entry[j].getFile();

				try
				{
					AMedia media = new AMedia(file, mimeMap.getContentType(file), null);
					DynamicMediaLink link = new DynamicMediaLink();
					innerRow = new Row();
					innerRow.setGroup(innerRowGroup);
					innerRows.appendChild(innerRow);
					innerRow.appendChild(link);

					link.setImage(ThemeManager.getThemeResource("images/Attachment16.png"));
					link.setTooltip(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Attachment")));
					link.setMedia(media);
					link.setLabel(media.getName());
				} catch (FileNotFoundException e) {
					;
				}
			}//for
		}

		innerRowGroup.setOpen(isOpen);
		innerRow.setVisible(true);

	}

	@Override
	public void prepareMessage(ArrayList<MBroadcastMessage> arrMessages) {
		mbMessages = arrMessages;
	}

	@Override
	public void onEvent(Event event) throws Exception {
		Component comp = event.getTarget();
	
		if(event.getName().equals(Events.ON_CLICK)){
			for (MBroadcastMessage mbMessage : mbMessages) {
				Checkbox isProcess = hashAcknowledged.get(mbMessage.get_ID());
	            if(comp == isProcess){
	       			if (isProcess.isSelected()){
	       				MNote note = getMNote(mbMessage);
	       				note.setProcessed(true);
	       				note.saveEx();
	       				isProcess.setEnabled(false);
	       			}
	        	}				
			}
		}		
	}
	
	/**
	 * Get AD Note entries for current login user for provided message
	 * @param mbMessage
	 * @return
	 */
	public MNote getMNote(MBroadcastMessage mbMessage) {
		MNote note =null;
		if(!mbMessage.getBroadcastType().equals(MBroadcastMessage.BROADCASTTYPE_Immediate)){
			String sql = "SELECT * FROM AD_Note WHERE AD_BroadcastMessage_ID = ? AND AD_User_ID = ? AND AD_Client_ID in (?, 0)";
			PreparedStatement pstmt = null;
			ResultSet rs=null;
			try {
				pstmt = DB.prepareStatement(sql, null);
				pstmt.setInt(1, mbMessage.get_ID());
				pstmt.setInt(2, Env.getAD_User_ID(Env.getCtx()));
				pstmt.setInt(3, Env.getAD_Client_ID(Env.getCtx()));
				rs = pstmt.executeQuery();
				if(rs.next())
					note = new MNote(Env.getCtx(), rs, null);
			} catch (Exception e) {
				logger.log(Level.SEVERE, "Note for the Message Could not be retrieved ",e);
				throw new DBException(e);
			}finally{
				DB.close(rs, pstmt);
			}
		}
		return note;
	}

	@Override
	public boolean isPooling() {
		return true;
	}
	
	@Override
    public void refresh(ServerPushTemplate template)
	{
		initRows();
		template.executeAsync(this);
	}

	@Override
	public void handleEvent(org.osgi.service.event.Event event) {
//		String eventName = event.getTopic();
//		if (eventName.equals(IEventTopics.BROADCAST_MESSAGE)) {
//			EventListener<Event> listner = new EventListener<Event>() {
//
//				@Override
//				public void onEvent(Event event) throws Exception {
//					BroadCastMsg msg = (BroadCastMsg) event.getData();
//
//					switch (msg.getEventId()) {
//					case BroadCastUtil.EVENT_TEST_BROADCAST_MESSAGE:
//						break;
//					case BroadCastUtil.EVENT_BROADCAST_MESSAGE:
//						MBroadcastMessage mbMessage = MBroadcastMessage.get(
//								Env.getCtx(), msg.getIntData());
//						if (mbMessage.isValidUserforMessage()) {
//						}
//						break;
//					case BroadCastUtil.EVENT_SESSION_TIMEOUT:
//						break;
//					case BroadCastUtil.EVENT_SESSION_ONNODE_TIMEOUT:
//						break;
//					}
//				}
//			};
//		}
	}
	
}
